#include "mpHttpParams.h"
#include "mpHttpConfig.h"
#include "mpHttpClient.h"
#include "Internal/mpHttpClientImpl.h"
#include "Internal/mpHttpClientAsyncImpl.h"

using namespace MP::HTTP::INTERNAL;

namespace MP{
namespace HTTP{

/*****************************************
 * HttpClientBase
 *****************************************/

HttpClientBase::HttpClientBase() :_baseAddress("http","127.0.0.1",80,"/"),_defaultRequestHeaders()
{
    _connect_timeout = HttpConfig::GetInstance().get_http_connect_timeout();
    _write_timeout = HttpConfig::GetInstance().get_http_write_timeout();
    _read_timeout = HttpConfig::GetInstance().get_http_read_timeout();
}

//boost::asio::io_context& HttpClientBase::getIoContext(){
//    return *_io_context;
//}

Url& HttpClientBase::getBaseAddress(){
    return _baseAddress;
}

HttpRequestHeaders& HttpClientBase::getDefaultRequestHeaders(){
    return _defaultRequestHeaders;
}

//设置建立连接的超时时间（单位：秒，默认值5）
void HttpClientBase::set_connect_timeout(int sec) {
    if (sec > 0) {
        _connect_timeout = sec;
    }
}

//获取建立连接的超时时间（单位：秒，默认值5）
int HttpClientBase::get_connect_timeout() const{
    return _connect_timeout;
}

//设置请求中写入data的超时时间（单位：秒，默认值30）
void HttpClientBase::set_write_timeout(int sec) {
    if (sec > 0) {
        _write_timeout = sec;
    }
}

//获取请求中写入data的超时时间（单位：秒，默认值30）
int HttpClientBase::get_write_timeout() const{
    return _write_timeout;
}

//设置请求中读取data的超时时间（单位：秒，默认值30）
void HttpClientBase::set_read_timeout(int sec) {
    if (sec > 0) {
        _read_timeout = sec;
    }
}

//获取请求中读取data的超时时间（单位：秒，默认值30）
int HttpClientBase::get_read_timeout() const{
    return _read_timeout;
}

void HttpClientBase::initHttpRequestMessageHeaders(HttpRequestMessage::ptr_s requestMessage){

    for(auto &item : _defaultRequestHeaders.data()) // 引用也可以不加，当需要节省空间时可以加上
    {
        requestMessage->getHttpRequestHeaders().addHeader(item.key,item.value);
    }

    requestMessage->getHttpRequestHeaders().setUserAgent(_defaultRequestHeaders.getUserAgent());
    requestMessage->getHttpRequestHeaders().setAccept(_defaultRequestHeaders.getAccept());
    requestMessage->getHttpRequestHeaders().setAcceptEncoding(_defaultRequestHeaders.getAcceptEncoding());
    requestMessage->getHttpRequestHeaders().setAuthorization(_defaultRequestHeaders.getAuthorization());

    requestMessage->getHttpRequestHeaders().setConnectionKeepalive(_defaultRequestHeaders.getConnectionKeepalive());
    if(_defaultRequestHeaders.getCache_Control() == MP::HTTP::HK_CACHE_CONTROL_NO_CACHE){
        requestMessage->getHttpRequestHeaders().setNoCache();
    }
    else{
        requestMessage->getHttpRequestHeaders().setCache_Control(_defaultRequestHeaders.getCache_Control());
    }
}

/*****************************************
 * HttpClient 同步请求类
 *****************************************/

HttpClient::HttpClient()
    :HttpClientBase()
{

}

/*****************************************
 * HttpClient 异步请求类
 *****************************************/

HttpClientAsync::HttpClientAsync()
    :HttpClientBase()
{

}

/*****************************************
 * 创建 HttpClient
 *****************************************/

HttpClient::ptr_s createHttpClient(/*bool useShardContext*/){
    return std::make_shared<HttpClientImpl>();
//    if(useShardContext){
//        return std::make_shared<HttpClientImpl>(getSharedHttpWorkContext());
//    }
//    else{
//        return std::make_shared<HttpClientImpl>();
//    }
}

HttpClient::ptr_s createHttpClientUseName(const std::string& name){

    HttpClient::ptr_s result = createHttpClient();
    HttpConfig::GetInstance().get_client_default_url(name,result->getBaseAddress());
    return result;
}

HttpClient::ptr_s createHttpClientUseUrl(const Url& baseAddress){

    HttpClient::ptr_s result = createHttpClient();

    result->getBaseAddress().setScheme(baseAddress.getScheme());
    result->getBaseAddress().setHost(baseAddress.getHost());
    result->getBaseAddress().setPort(baseAddress.getPort());
    result->getBaseAddress().setRelativeUri(baseAddress.getRelativeUri());

    return result;
}

HttpClientAsync::ptr_s createHttpClientAsync(boost::asio::io_context& io_context){
    return std::make_shared<HttpClientAsyncImpl>(io_context);
}

HttpClientAsync::ptr_s createHttpClientAsyncUseName(boost::asio::io_context& io_context,
                                                    const std::string& name){

    HttpClientAsync::ptr_s result = createHttpClientAsync(io_context);
    HttpConfig::GetInstance().get_client_default_url(name,result->getBaseAddress());
    return result;
}

HttpClientAsync::ptr_s createHttpClientAsyncUseUrl(boost::asio::io_context& io_context,
                                                   const Url& baseAddress){

    HttpClientAsync::ptr_s result = createHttpClientAsync(io_context);

    result->getBaseAddress().setScheme(baseAddress.getScheme());
    result->getBaseAddress().setHost(baseAddress.getHost());
    result->getBaseAddress().setPort(baseAddress.getPort());
    result->getBaseAddress().setRelativeUri(baseAddress.getRelativeUri());

    return result;
}


}   //HTTP
}   //MP
